cmake_minimum_required(VERSION 3.10)
project(servo_visual)

# ===== 编译选项（可选但推荐）=====
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_POSITION_INDEPENDENT_CODE ON)

# ===== 依赖 =====
find_package(ament_cmake REQUIRED)
find_package(rclcpp REQUIRED)
find_package(rclcpp_components REQUIRED)
find_package(geometry_msgs REQUIRED)
find_package(tf2 REQUIRED)
find_package(tf2_ros REQUIRED)
find_package(tf2_geometry_msgs REQUIRED)
find_package(sensor_msgs REQUIRED)
find_package(moveit_core REQUIRED)
find_package(moveit_ros_planning REQUIRED)
find_package(control_msgs REQUIRED)
find_package(moveit_servo REQUIRED)
find_package(moveit_ros_planning_interface REQUIRED)
find_package(Eigen3 REQUIRED)
find_package(std_msgs REQUIRED)

# ===== 组件库：IBVS =====
add_library(servo_visual_ibvs SHARED
  src/ibvs_control.cpp
)
target_include_directories(servo_visual_ibvs PUBLIC
  $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
  $<INSTALL_INTERFACE:include>
)
ament_target_dependencies(servo_visual_ibvs
  rclcpp rclcpp_components
  geometry_msgs sensor_msgs
  tf2 tf2_ros tf2_geometry_msgs
  moveit_core moveit_ros_planning
  moveit_servo control_msgs  
)
# 注册组件（类名需要与实现一致）
rclcpp_components_register_nodes(servo_visual_ibvs "servo_visual::IBVSControl")
# 导出带命名空间别名
add_library(servo_visual::ibvs_control ALIAS servo_visual_ibvs)

# ===== 组件库：Visual =====
add_library(servo_visual_visual SHARED
  src/visual_control.cpp
)
target_include_directories(servo_visual_visual PUBLIC
  $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
  $<INSTALL_INTERFACE:include>
)
ament_target_dependencies(servo_visual_visual
  rclcpp rclcpp_components
  geometry_msgs sensor_msgs
  tf2 tf2_ros tf2_geometry_msgs
  moveit_core moveit_ros_planning
  moveit_servo control_msgs  
)
rclcpp_components_register_nodes(servo_visual_visual "servo_visual::VisualControl")
add_library(servo_visual::visual_control ALIAS servo_visual_visual)

# ===== 独立可执行：包装 main（便于 ros2 run）=====
add_executable(ibvs_control_node src/ibvs_control_main.cpp)
target_link_libraries(ibvs_control_node servo_visual::ibvs_control)
ament_target_dependencies(ibvs_control_node rclcpp)

add_executable(visual_control_node src/visual_control_main.cpp)
target_link_libraries(visual_control_node servo_visual::visual_control)
ament_target_dependencies(visual_control_node rclcpp)

# ===== 安装与导出 =====
install(TARGETS
  servo_visual_ibvs
  servo_visual_visual
  # ibvs_control_node
  # visual_control_node         # 不导出可执行
  EXPORT export_servo_visual    # ✅ 只导出库
  RUNTIME DESTINATION lib/${PROJECT_NAME}
  LIBRARY DESTINATION lib
  ARCHIVE DESTINATION lib
)
install(TARGETS
  ibvs_control_node
  visual_control_node
  RUNTIME DESTINATION lib/${PROJECT_NAME}
)
install(DIRECTORY include/ DESTINATION include)
install(DIRECTORY launch/ DESTINATION share/${PROJECT_NAME}/launch)

add_executable(once_control src/once_control.cpp)
ament_target_dependencies(once_control
  rclcpp
  geometry_msgs
  std_msgs
  moveit_ros_planning_interface
  moveit_ros_planning
  tf2
  tf2_ros
)
# 这里必须用 plain 签名（无 PRIVATE/PUBLIC），以避免和上面的 ament_* 混用
target_link_libraries(once_control Eigen3::Eigen)

install(TARGETS once_control
  RUNTIME DESTINATION lib/${PROJECT_NAME}
)
install(TARGETS once_control
  RUNTIME DESTINATION lib/${PROJECT_NAME}
)
ament_export_targets(export_servo_visual HAS_LIBRARY_TARGET)
ament_export_include_directories(include)
ament_export_dependencies(
  rclcpp
  rclcpp_components
  geometry_msgs
  sensor_msgs
  tf2
  tf2_ros
  tf2_geometry_msgs
  moveit_core
  moveit_ros_planning
  moveit_servo
  control_msgs
)


ament_package()
